/* eslint-disable func-names */
/* eslint-disable consistent-return */
const mongoose = require('mongoose');

/**
 * Config Schema
 * @description Schema for ECharts configuration storage
 */
const configSchema = new mongoose.Schema(
  {
    name: {
      type: String,
      required: [true, 'Name is required'],
      trim: true,
      maxlength: [100, 'Name cannot be more than 100 characters'],
    },
    description: {
      type: String,
      trim: true,
      maxlength: [500, 'Description cannot be more than 500 characters'],
    },
    config: {
      type: mongoose.Schema.Types.Mixed,
      required: [true, 'Chart configuration is required'],
    },
    tags: {
      type: [String],
      default: [],
    },
    createdBy: {
      type: String,
      default: 'system',
    },
    updatedBy: {
      type: String,
      default: 'system',
    },
  },
  {
    timestamps: true,
    toJSON: { virtuals: true },
    toObject: { virtuals: true },
  },
);

// Add text index for search functionality
configSchema.index({ name: 'text', description: 'text', tags: 'text' });

// Pre-save hook to validate config object
configSchema.pre('save', function (next) {
  if (!this.config || Object.keys(this.config).length === 0) {
    return next(new Error('Config object cannot be empty'));
  }
  next();
});

// Static method to search configs
configSchema.statics.searchConfigs = async function (searchTerm, options = {}) {
  const {
    page = 1, limit = 10, sortBy = 'createdAt', order = 'desc',
  } = options;
  const skip = (page - 1) * limit;

  const query = searchTerm
    ? { $text: { $search: searchTerm } }
    : {};

  const [configs, total] = await Promise.all([
    this.find(query)
      .sort({ [sortBy]: order })
      .skip(skip)
      .limit(limit),
    this.countDocuments(query),
  ]);

  return {
    configs,
    total,
    page: parseInt(page, 10),
    limit: parseInt(limit, 10),
  };
};

const Config = mongoose.model('Config', configSchema);

module.exports = Config;
